package com.app.business.service;

import com.app.business.en.Status;
import com.app.business.model.*;
import com.app.system.jpa.JpaBaseDao;
import com.app.system.permission.model.SysRole;
import com.app.system.utils.CollectionUtils;
import com.app.system.utils.ParamUtils;
import com.app.system.utils.WebUtils;
import com.app.system.utils.dataType.BigDecimalUtils;
import com.app.system.utils.exception.Precondition;
import com.app.system.utils.exception.Response;
import com.google.common.collect.Maps;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.Query;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * 产权人业务层
 * Created by ZYK on 2019/2/25.
 */
@Service
@Transactional
@SuppressWarnings("all")
public class BuyHousePersonService extends JpaBaseDao<BuyHousePerson, Integer> {

    @Autowired
    private CarLotService carLotService;
    @Autowired
    private HouseService houseService;
    @Autowired
    private ContractService contractService;
    @Autowired
    private StorageRoomService storageRoomService;
    @Autowired
    private CarLotBuyPersonService carLotBuyPersonService;
    @Autowired
    private HouseBuyPersonService houseBuyPersonService;
    @Autowired
    private StorageRoomPersonService storageRoomPersonService;
    @Autowired
    private ActionHistoryService actionHistoryService;
    @Autowired
    private ShopHouseBuyPersonService shopHouseBuyPersonService;
    @Autowired
    private ShopHouseService shopHouseService;

    /**
     * 根据协议Id得到购房人列表
     *
     * @param contractId
     * @return
     */
    public List<BuyHousePerson> getBuyHousePersonListByContractId(Integer contractId) {
        //查询语句
        String hql = " from BuyHousePerson bh where bh.contract.id = :contractId order by bh.id";
        Map<String, Object> map = new HashMap<>();
        map.put("contractId", contractId);
        return this.findHql(hql, map);
    }

    public List<BuyHousePerson> getBuyHousePersonListByBuyHousePersonId(List<String> ids, Integer contractId) {
        //查询语句
        String hql = " from BuyHousePerson bh where bh.contract.id = :contractId and bh.id in:ids";
        Map<String, Object> map = new HashMap<>();
        map.put("contractId", contractId);
        map.put("ids", ids);
        return this.findHql(hql, map);
    }

    /**
     * 设置购房人
     *
     * @param ids,houseId,carLotId
     */
    @Transactional
    public String setBuyHousePerson(String[] ids, Integer houseId, Integer carLotId, Integer storageRoomId,Integer shopHouseId) {
        this.carLotBuyPersonService.deleteCarLotBuyPersonByCarLotId(carLotId);
        this.houseBuyPersonService.deleteHouseBuyPersonByHouseId(houseId);
        this.storageRoomPersonService.deleteStorageRoomBuyPersonByStorageRoomId(storageRoomId);
        this.shopHouseBuyPersonService.deleteShopHouseBuyPersonByShopHousetId(shopHouseId);
        Set<SysRole> list = WebUtils.getLoginUserInfo().getRoleList();
        String doName = "";
        for (SysRole sysRole : list) {
            doName = doName + "-" + sysRole.getRole() + "-";
        }

        if (ids != null) {
            if (carLotId != null && carLotId != 0) {
                Precondition.checkSqdsArguement(carLotId != null && carLotId != 0, "该车位不存在！");
                CarLot carLot = this.carLotService.findOne(carLotId);
/*
                Precondition.checkAjaxArguement(carLot.getContract().getAzSignStatus() != 2, "1111", "该户已签约！");
*/
                for (String id : ids) {
                    CarLotBuyPerson carLotBuyPerson = new CarLotBuyPerson();
                    carLotBuyPerson.setBuyHousePersonId(Integer.valueOf(id));
                    carLotBuyPerson.setCarLotId(carLotId);
                    this.carLotBuyPersonService.save(carLotBuyPerson);
                    this.actionHistoryService.saveActionHistoryByContractId(carLot.getContract().getId(), "设置ID为" + carLotBuyPerson.getCarLotId() + "的车位的产权人ID为：" + carLotBuyPerson.getBuyHousePersonId(), "设置车位产权人");
                }
            } else if (houseId != null && houseId != 0) {
                Precondition.checkSqdsArguement(houseId != null && houseId != 0, "该房源不存在！");
                House house = this.houseService.findOne(houseId);

                /*if (doName.contains("-管理员-")) {

                } else if (doName.contains("-物业管理员-") || doName.contains("-物业操作员-")) {
                    Precondition.checkAjaxArguement(house.getContract().getTakeHouseStatus() != null && house.getContract().getTakeHouseStatus().equals(Status.YES.getIndex()), "1111", "该家庭暂未交房！");
                } else {
                    Precondition.checkAjaxArguement(house.getContract().getLimitStatus() != null && house.getContract().getLimitStatus().equals(Status.NO.getIndex()), "4444", "该家庭当前暂不能进行操作！");
                    Precondition.checkAjaxArguement(house.getContract().getAzSignStatus() != 2, "1111", "该户已签约！");
                }*/
                for (String id : ids) {
                    HouseBuyPerson houseBuyPerson = new HouseBuyPerson();
                    houseBuyPerson.setBuyHousePersonId(Integer.valueOf(id));
                    houseBuyPerson.setHouseId(houseId);
                    this.houseBuyPersonService.save(houseBuyPerson);
                    this.actionHistoryService.saveActionHistoryByContractId(house.getContract().getId(), "设置ID为" + houseBuyPerson.getHouseId() + "的房源的产权人ID为：" + houseBuyPerson.getBuyHousePersonId(), "设置房源产权人");

                }
            } else if (storageRoomId != null && storageRoomId != 0) {
                Precondition.checkSqdsArguement(storageRoomId != null && storageRoomId != 0, "该储物间不存在！");
                StorageRoom storageRoom = this.storageRoomService.findOne(storageRoomId);
/*
                Precondition.checkAjaxArguement(storageRoom.getContract().getAzSignStatus() != 2, "1111", "该户已签约！");
*/
                for (String id : ids) {
                    StorageRoomBuyPerson storageRoomBuyPerson = new StorageRoomBuyPerson();
                    storageRoomBuyPerson.setBuyHousePersonId(Integer.valueOf(id));
                    storageRoomBuyPerson.setStorageRoomId(storageRoomId);
                    this.storageRoomPersonService.save(storageRoomBuyPerson);
                    this.actionHistoryService.saveActionHistoryByContractId(storageRoom.getContract().getId(), "设置ID为" + storageRoomBuyPerson.getStorageRoomId() + "的储物间的产权人ID为：" + storageRoomBuyPerson.getBuyHousePersonId(), "设置储物间产权人");

                }
            } else if (shopHouseId != null && shopHouseId != 0) {
                Precondition.checkSqdsArguement(shopHouseId != null && shopHouseId != 0, "该店面不存在！");
                ShopHouse shopHouse = this.shopHouseService.findOne(shopHouseId);
/*
                Precondition.checkAjaxArguement(shopHouse.getContract().getAzSignStatus() != 2, "1111", "该户已签约！");
*/
                for (String id : ids) {
                    ShopHouseBuyPerson shopHouseBuyPerson = new ShopHouseBuyPerson();
                    shopHouseBuyPerson.setBuyHousePersonId(Integer.valueOf(id));
                    shopHouseBuyPerson.setShopHouseId(shopHouseId);
                    this.shopHouseBuyPersonService.save(shopHouseBuyPerson);
                    this.actionHistoryService.saveActionHistoryByContractId(shopHouse.getContract().getId(), "设置ID为" + shopHouseBuyPerson.getShopHouseId() + "的店面的产权人ID为：" + shopHouseBuyPerson.getBuyHousePersonId(), "设置店面产权人");

                }
            }
        }
        return "ok";
    }


    /**
     * 产权人身份证号验证查重
     *
     * @param contractId
     * @param zsProjectId
     * @param chooseHouseNum
     * @return
     */
    public String validateIdCard(Integer contractId, Integer buyHousePersonId, String idCard) {
        StringBuffer hql = new StringBuffer(" select * from buy_house_person where id != :buyHousePersonId and contract_id =:contractId and id_card =:idCard ");
        Map<String, Object> map = Maps.newLinkedHashMap();
        map.put("idCard", idCard);
        map.put("buyHousePersonId", buyHousePersonId);
        map.put("contractId", contractId);

        List list = this.findSqlObject(hql.toString(), map);
        if (CollectionUtils.isNotEmpty(list)) {
            return "该身份证号已存在";
        }
        return null;

    }

    /**
     * 得到房源id和当前房源的List<buyHousePerson>对应的map
     *
     * @param buyHousePersonList
     * @return
     */
    public Map<String, List<Map>> getBuyHousePersonByHouse() {
        List<Map> valueList = null;
        StringBuffer sql = new StringBuffer(" SELECT * FROM buy_house_person b, ");
        sql.append(" (SELECT hbp.house_id AS houseId ,hbp.buy_house_person_id AS buyHousePersonId FROM house_buy_person hbp ) a");
        sql.append(" WHERE b.id = a.buyHousePersonId ");
        Query query = this.entityManager.createNativeQuery(sql.toString());
        List<Map> buyHousePersonList = query.unwrap(org.hibernate.SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
        Map<String, List<Map>> map = Maps.newLinkedHashMap();
        if (CollectionUtils.isNotEmpty(buyHousePersonList)) {
            for (Map map1 : buyHousePersonList) {
                String houseId = String.valueOf(map1.get("houseId"));
                valueList = map.get(houseId) == null ? new ArrayList<>() : map.get(houseId);
                valueList.add(map1);
                map.put(houseId, valueList);
            }
        }
        return map;
    }

    public Map<String, List<Map>> getBuyHousePersonByCarLot() {
        List<Map> valueList = null;
        StringBuffer sql = new StringBuffer(" SELECT * FROM buy_house_person b, ");
        sql.append(" (SELECT cbp.car_lot_id AS carLotId ,cbp.buy_house_person_id AS buyHousePersonId FROM car_lot_buy_person cbp ) c");
        sql.append(" WHERE b.id = c.buyHousePersonId ");
        Query query = this.entityManager.createNativeQuery(sql.toString());
        List<Map> buyHousePersonList = query.unwrap(org.hibernate.SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
        Map<String, List<Map>> map = Maps.newLinkedHashMap();
        if (CollectionUtils.isNotEmpty(buyHousePersonList)) {
            for (Map map1 : buyHousePersonList) {
                String carLotId = String.valueOf(map1.get("carLotId"));
                valueList = map.get(carLotId) == null ? new ArrayList<>() : map.get(carLotId);
                valueList.add(map1);
                map.put(carLotId, valueList);
            }
        }
        return map;
    }


    public Map<String, List<Map>> getBuyHousePersonByStorageRoom() {
        List<Map> valueList = null;
        StringBuffer sql = new StringBuffer(" SELECT * FROM buy_house_person b, ");
        sql.append(" (SELECT sbp.storage_room_id AS storageRoomId ,sbp.buy_house_person_id AS buyHousePersonId FROM storage_room_buy_person sbp ) c");
        sql.append(" WHERE b.id = c.buyHousePersonId ");
        Query query = this.entityManager.createNativeQuery(sql.toString());
        List<Map> buyHousePersonList = query.unwrap(org.hibernate.SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
        Map<String, List<Map>> map = Maps.newLinkedHashMap();
        if (CollectionUtils.isNotEmpty(buyHousePersonList)) {
            for (Map map1 : buyHousePersonList) {
                String storageRoomId = String.valueOf(map1.get("storageRoomId"));
                valueList = map.get(storageRoomId) == null ? new ArrayList<>() : map.get(storageRoomId);
                valueList.add(map1);
                map.put(storageRoomId, valueList);
            }
        }
        return map;
    }

    public Map<String, List<Map>> getBuyHousePersonByShopHouse() {
        List<Map> valueList = null;
        StringBuffer sql = new StringBuffer(" SELECT * FROM buy_house_person b, ");
        sql.append(" (SELECT cbp.shop_house_id AS shopHouseId ,cbp.buy_house_person_id AS buyHousePersonId FROM shop_house_buy_person cbp ) c");
        sql.append(" WHERE b.id = c.buyHousePersonId ");
        Query query = this.entityManager.createNativeQuery(sql.toString());
        List<Map> buyHousePersonList = query.unwrap(org.hibernate.SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
        Map<String, List<Map>> map = Maps.newLinkedHashMap();
        if (CollectionUtils.isNotEmpty(buyHousePersonList)) {
            for (Map map1 : buyHousePersonList) {
                String carLotId = String.valueOf(map1.get("shopHouseId"));
                valueList = map.get(carLotId) == null ? new ArrayList<>() : map.get(carLotId);
                valueList.add(map1);
                map.put(carLotId, valueList);
            }
        }
        return map;
    }

    /**
     * 协议对应下的产权人数量
     * @return
     */
    public Map<String, String> getBuyHousePersonNumByContractId() {
        List<Map> valueList = null;
        StringBuffer sql = new StringBuffer(" SELECT  b.contract_id AS 'contractId',COUNT(b.id) AS 'num' ");
        sql.append("FROM buy_house_person b ");
        sql.append("GROUP BY b.contract_id ");
        Query query = this.entityManager.createNativeQuery(sql.toString());
        List<Map> buyHousePersonList = query.unwrap(org.hibernate.SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
        Map<String, String> map = Maps.newLinkedHashMap();
        if (CollectionUtils.isNotEmpty(buyHousePersonList)) {
            for (Map mapItem : buyHousePersonList){
                String contractId = mapItem.get("contractId").toString();
                String num = mapItem.get("num").toString();
                map.put(contractId,num);
            }
        }

        return map;
    }

    /**
     * 根据房源id得到购房人列表
     *
     * @param houseId
     * @return
     */
    public List<BuyHousePerson> getBuyHousePersonListByHouseId(Integer houseId) {
        List<Integer> ids = this.houseBuyPersonService.getBuyHousePersonIdListByHouseIdForInteger(houseId);

        ids.add(0);
        String hql = " from BuyHousePerson bh where bh.id in (:ids) order by bh.id";
        //查询语句
        Map<String, Object> map = new HashMap<>();
        map.put("ids", ids);
        return this.findHql(hql, map);
    }


    /**
     * 根据车位id得到购房人列表
     *
     * @param houseId
     * @return
     */
    public List<BuyHousePerson> getBuyHousePersonListByCarLotId(Integer carLotId) {
        List<Integer> ids = this.carLotBuyPersonService.getBuyHousePersonIdListByCarLotIdForInteger(carLotId);

        ids.add(0);
        String hql = " from BuyHousePerson bh where bh.id in (:ids) order by bh.id";
        //查询语句
        Map<String, Object> map = new HashMap<>();
        map.put("ids", ids);
        return this.findHql(hql, map);
    }

    /**
     * 根据储物间id得到购房人列表
     *
     * @param houseId
     * @return
     */
    public List<BuyHousePerson> getBuyHousePersonListByStorageRoomId(Integer storageRoomId) {
        List<Integer> ids = this.storageRoomPersonService.getBuyHousePersonIdListByStorageRoomIdForInteger(storageRoomId);

        ids.add(0);
        String hql = " from BuyHousePerson bh where bh.id in (:ids) order by bh.id";
        //查询语句
        Map<String, Object> map = new HashMap<>();
        map.put("ids", ids);
        return this.findHql(hql, map);
    }


    /**
     * 产权人信息保存
     *
     * @param request
     * @return
     */
    public synchronized Response savBuyHousePersonType(HttpServletRequest request) {
        int contractId = ParamUtils.getInt(request, "contractId", 0);
        Contract contract = this.contractService.findOne(contractId);

        Precondition.checkAjaxArguement(contract != null, "1111", "未找到协议信息，保存失败！");

        this.contractService.save(contract);
        //保存之前先删除数据

        String[] idsArray = ParamUtils.getStringParameters(request, "buyHousePersonId");
        String[] telArray = ParamUtils.getStringParameters(request, "tel");
        String[] relationArray = ParamUtils.getStringParameters(request, "relation");
        String[] typeArray = ParamUtils.getStringParameters(request, "type");
        String[] memoArray = ParamUtils.getStringParameters(request, "memo");
        //必须不为空，且长度一致（必填）
        Precondition.checkAjaxArguement(idsArray != null, "2222", "找不到该产权人！");
        int length = idsArray.length;
        String id = null, tel = null, relation = null, type = null, memo = null;
        for (int i = 0; i < length; i++) {
            id = null;
            tel = null;
            relation = null;
            type = null;
            memo = null;
            id = idsArray[i];
            tel = telArray[i];
            relation = relationArray[i];
            type = typeArray[i];
            memo = memoArray[i];
            BuyHousePerson buyHousePerson = this.findOne(Integer.valueOf(id));
            Precondition.checkAjaxArguement(buyHousePerson != null, "2222", "找不到该产权人！");
            buyHousePerson.setTel(tel);
            buyHousePerson.setType(type);
            buyHousePerson.setRelation(relation);
            buyHousePerson.setMemo(memo);
            this.save(buyHousePerson);

        }
        return new Response("0001", "保存成功!");
    }

    /**
     * 协议下多个安置区
     *
     * @param contractId
     * @return
     */
    public String azProjectName(Integer contractId) {
        StringBuffer hql = new StringBuffer("  ");
        hql.append(" SELECT ap.project_name FROM house h LEFT JOIN az_project ap ON h.az_project_id = ap.id " +
                "WHERE h.contract_id =:contractId GROUP BY ap.project_name " +
                "UNION " +
                "SELECT ap.project_name FROM Storage_Room s LEFT JOIN az_project ap ON s.az_project_id = ap.id " +
                "WHERE s.contract_id =:contractId GROUP BY ap.project_name " +
                "UNION " +
                "SELECT ap.project_name FROM Car_Lot c LEFT JOIN az_project ap ON c.az_project_id = ap.id " +
                "WHERE c.contract_id =:contractId GROUP BY ap.project_name ");
        Map<String, Object> map = Maps.newLinkedHashMap();
        map.put("contractId", contractId);

        List list = this.findSqlObject(hql.toString(), map);
        String azProjectNameStr = "";
        if (CollectionUtils.isNotEmpty(list)) {
            for (Object obj : list) {
                azProjectNameStr = azProjectNameStr + String.valueOf(obj);
                if (list.size() - 1 != list.indexOf(obj)) {//若是到最后一步
                    azProjectNameStr = azProjectNameStr + "、";
                }
            }
            return azProjectNameStr;
        }
        return azProjectNameStr;

    }


    /**
     * 协议下多个安置区
     *
     * @param contractId
     * @return
     */
    public List<String> getHouseNameList(Integer contractId, Integer jkStatus) {

        List<House> houseList = new ArrayList<>();
        if (jkStatus == 1) {
            houseList = this.houseService.getHouseListByContractId(contractId);
        } else if (jkStatus == 2) {
            houseList = this.houseService.getHandInMoneyHouseListByContractId(contractId);
        }
        String buyHousePersonName = "";

        List<String> housePersonNameList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(houseList)) {
            for (House house : houseList) {
                buyHousePersonName = "";
                List<BuyHousePerson> buyHousePersonList = this.getBuyHousePersonListByHouseId(house.getId());
                if (!CollectionUtils.isEmpty(buyHousePersonList)) {
                    for (BuyHousePerson buyHousePerson : buyHousePersonList) {
                        if (buyHousePersonList.size() - 1 == buyHousePersonList.indexOf(buyHousePerson)) {
                            buyHousePersonName = buyHousePersonName + buyHousePerson.getName();
                        } else {
                            buyHousePersonName = buyHousePersonName + buyHousePerson.getName() + "、";
                        }
                        housePersonNameList.add(buyHousePerson.getName());
                    }
                }
            }
        }

        List<CarLot> carLotList = new ArrayList<>();
        if (jkStatus == 1) {
            carLotList = this.carLotService.getCarLotListByContractId(contractId);
        } else if (jkStatus == 2) {
            carLotList = this.carLotService.getHandInMoneyCarLotListByContractId(contractId);
        }
        if (!CollectionUtils.isEmpty(carLotList)) {
            for (CarLot carLot : carLotList) {
                buyHousePersonName = "";
                List<BuyHousePerson> buyHousePersonList = this.getBuyHousePersonListByCarLotId(carLot.getId());
                if (!CollectionUtils.isEmpty(buyHousePersonList)) {
                    for (BuyHousePerson buyHousePerson : buyHousePersonList) {
                        if (buyHousePersonList.size() - 1 == buyHousePersonList.indexOf(buyHousePerson)) {
                            buyHousePersonName = buyHousePersonName + buyHousePerson.getName();
                        } else {
                            buyHousePersonName = buyHousePersonName + buyHousePerson.getName() + "、";
                        }
                        housePersonNameList.add(buyHousePerson.getName());
                    }
                }
            }
        }
        HashSet<String> set = new HashSet<>(housePersonNameList);
        List<String> list = new ArrayList<>(set);
        return list;
    }

    /**
     * 删除协议对应下的所有产权人信息
     * @param contractId
     */
    public synchronized void deleteBuyHousePersonByContractId(Integer contractId) {
        String sql = "delete from buy_house_person where contract_id = :contractId";
        this.entityManager.createNativeQuery(sql).setParameter("contractId", contractId).executeUpdate();
    }

    /**
     * 征收项目参数配置数据保存
     * @param request
     * @return
     */
    public synchronized Response personDataFormSave(HttpServletRequest request){
        int contractId = ParamUtils.getInt(request, "contractId", 0);
        Contract contract = this.contractService.findOne(contractId);
        Precondition.checkAjaxArguement(contract.getAzSignStatus() != 2,"1111","安置协议已签订，无法更改！");
        Precondition.checkAjaxArguement(contract != null,"1111","未找到对应基础信息，保存失败！");

        //保存之前先删除数据
        this.deleteBuyHousePersonByContractId(contract.getId());

        String[] nameArray = ParamUtils.getStringParameters(request,"name");    //产权人姓名
        String[] idCardArray = ParamUtils.getStringParameters(request,"idCard");    //身份证号
        String[] telArray = ParamUtils.getStringParameters(request,"tel");    //联系方式
        String[] relationArray = ParamUtils.getStringParameters(request,"relation");    //与被征收人关系
        String[] typeArray = ParamUtils.getStringParameters(request,"type");    //产权获得方式
        String[] memoArray = ParamUtils.getStringParameters(request,"memo");    //备注
        //必须不为空，且长度一致（必填）
        int length = nameArray.length;
        String name = null,idCard = null,tel = null,relation = null,type = null,memo = null;
        for (int i = 0; i < length; i++){
            name = null;idCard = null;tel = null;relation = null;type = null;memo = null;

            name = nameArray[i];idCard = idCardArray[i];tel = telArray[i];relation = relationArray[i];type = typeArray[i];memo = memoArray[i];
            if (name != null && !name.equals("") && idCard != null && !idCard.equals("") && tel != null && !tel.equals("") && relation != null && !relation.equals("")
                    && type != null && !type.equals("")){
                BuyHousePerson buyHousePerson = new BuyHousePerson();
                buyHousePerson.setName(name);
                buyHousePerson.setIdCard(idCard);
                buyHousePerson.setTel(tel);
                buyHousePerson.setRelation(relation);
                buyHousePerson.setType(type);
                buyHousePerson.setMemo(memo);
                buyHousePerson.setContract(contract);
                this.save(buyHousePerson);
            }
        }
        return new Response("0001", "保存成功!");
    }
}
